package com.astrob.activitys;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Typeface;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.astrob.NavFrameSDK;
import com.astrob.NavFrameSDK.CLonLat;
import com.astrob.NavFrameSDK.GuideInfo;
import com.astrob.NavFrameSDK.NavDest;
import com.astrob.NavFrameSDK.NavInfo;
import com.astrob.NavFrameSDK.NavPosition;
import com.astrob.NavFrameSDK.POIDescription;
import com.astrob.NavFrameSDK.RouteOption;
import com.astrob.NavFrameSDK.SDCurPosStates;
import com.astrob.NavFrameSDK.TurnInfo;
import com.astrob.model.FavoriteData;
import com.astrob.model.FavoriteFileHandle;
import com.astrob.model.HistoryData;
import com.astrob.model.HistoryFileHandle;
import com.astrob.model.LonLat;
import com.astrob.model.Msg;
import com.astrob.model.RoutePlanDataHandle;
import com.astrob.model.SystemSetFileHandle;
import com.astrob.naviframe.Start;
import com.astrob.nhcmap.R;
import com.astrob.util.SysUtils;
import com.astrob.util.Utils;
import com.astrob.view.Car;
import com.astrob.view.MapView;
import com.astrob.view.NaviInfoView;
import com.astrob.view.NaviModeCtrlView;
import com.astrob.view.TipInfoView;
import com.astrob.view.ZoomView;
import com.iflytek.tts.TtsService.TtsSpeaker;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class NaviActivity extends Activity implements SensorEventListener, PositionProvider.PosCallBack, View.OnClickListener {

	private MapView mMapView = null;

	// 放大缩小\查询
	private ZoomView mZoom = null;
	// 回现地
	private ImageButton mLocal = null;
	// 查询
	private FrameLayout mSearch = null;
	// 路线信息
	private ImageButton mNaviinfo = null;
	// 模式切换(2D + 3D + 地图指北)
	private NaviModeCtrlView mNavimodectrlView;

	// 导航信息
	private NaviInfoView mNaviInfoView; // 导航信息

	// scale
	private TextView mScale = null;
	// tipinfo
	private TipInfoView mTipInfo = null;
	// simu
	private FrameLayout mSimuCtrl = null;

	// 页面迁移前地图中心点
	private LonLat mCenterll = new LonLat();

	private LonLat mCarll = new LonLat();
	protected Car mCar = new Car();
	private PositionProvider mPosProvider = null;

	private boolean fromfav_ = false;
	private boolean mIsShowRoutePlan = false;
	private boolean mIsOnMap = false;

	private int mFromRouteMgrType = -1;
	private int mFromRouteMgrDestIndex = -1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		initUI();

		double dlon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
		double dlat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
		mCarll.SetLonLat(dlon, dlat);
		mTipll.SetLonLat(dlon, dlat);

		Bundle bundle = getIntent().getExtras();
		if (bundle != null) {
			dlon = bundle.getDouble("mapcenterlon");
			dlat = bundle.getDouble("mapcenterlat");
			mTipll.SetLonLat(dlon, dlat);
			if (mTipll.IsValid()) {
				Start.getInstance().MapKit().setMapCenter(dlon, dlat);
				mMapView.setTipLL(mTipll);
			}
			mFromRouteMgrType = bundle.getInt("TypeFlag", -1);
			mFromRouteMgrDestIndex = bundle.getInt("DestIndex", -1);
			mTipname = bundle.getString("poiname");
			if (mTipname == null) {
				mTipname = "";
			}
			mIsShowRoutePlan = bundle.getBoolean("showRoutePlan", false);
			mIsOnMap = bundle.getBoolean("showOnmap", false);
			fromfav_ = bundle.getBoolean("fromfav", false);
			if (Start.getInstance().MapKit().mTipPoiList == null) {
				Start.getInstance().MapKit().mTipPoiList = new ArrayList<POIDescription>();
			}
			Start.getInstance().MapKit().mTipPoiList.clear();
			ArrayList<POIDescription> poiList = Start.getInstance().MapKit().getNearPoi(
					new LonLat(dlon, dlat), false);
			for (int i = 0; i < poiList.size(); i++) {
				POIDescription poitip = poiList.get(i);
				String name = poitip.name.replace("*", " ");
				name = name.trim();
				if (name.compareTo(mTipname) == 0) {
					Start.getInstance().MapKit().mTipPoiList.add(poitip);
					break;
				}
			}

			if (mIsOnMap) {
				Start.getInstance().MapKit().setScale(100000);
				mMapView.setPOIMarkLL(dlon, dlat);
				TextView poimarkTv = (TextView) findViewById(R.id.title);
				poimarkTv.setText(mTipname);
			}
		}

		mScale.setText(Start.getInstance().MapKit().getScaleString());

		Start.getInstance().MapKit().setMapCenter(dlon, dlat);
		Start.getInstance().MapKit().setScale(100000);
		mCenterll.SetLonLat(dlon, dlat);

		mPosProvider = PositionProvider.getInstance();
		if (!mIsOnMap) {
			mPosProvider.init(this, this);
		}

		NavPosition matchCar = mCar.getCarNavPos();
		matchCar.pos.lon = mCarll.GetLon();
		matchCar.pos.lat = mCarll.GetLat();
		matchCar.signal = 100;
		mCar.setCarNavPos(matchCar);

		initWnd(MOVING_MODE);

		if (bundle != null) {
			boolean bNaviTo = bundle.getBoolean("isNaviToDest", false);
			if (bNaviTo) {
				DoNaviToDest();
			}
		}

		if (mTipname != null) {
			if (mTipname.length() > 1) {
				mTipname = mTipname.replace("*", "\n");
			}
			mTipInfo.setText(mTipname);
		}

		if (mFromRouteMgrType != -1) {
			// tip不要两边button
			mTipInfo.hideBtn();
		}

		if (mIsShowRoutePlan) {
			showRoutePlanDests();
		}

		if (mIsOnMap) {
			mSearch.setVisibility(View.INVISIBLE);
			mNaviInfoView.setVisibility(View.INVISIBLE);
			mNaviinfo.setVisibility(View.INVISIBLE);
		}

		// 取得SensorManager实例
		mRegisteredSensor = false;
		mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

		//注册文件 test
		String id = Settings.Secure.getString(this.getContentResolver(),
				Settings.System.ANDROID_ID);
		id = "1114170311001B00";
		String key = "";
		if (NavFrameSDK.IsRightUser(id, key)) {
			key = "sdfdf";
			return;
		}
	}

	private boolean mRegisteredSensor;
	private SensorManager mSensorManager;
	private float mSensorDegree = -1;

	private void showRoutePlanDests() {
		int nCount = RoutePlanDataHandle.getInstance().getDests().size();
		if (nCount <= 0)
			return;

		double minlon, minlat, maxlon, maxlat;
		ArrayList<HistoryData> dests = RoutePlanDataHandle.getInstance()
				.getDests();
		minlon = maxlon = dests.get(0).lon;
		minlat = maxlat = dests.get(0).lat;
		for (int i = 1; i < nCount; i++) {
			if (dests.get(i).lon < minlon)
				minlon = dests.get(i).lon;
			if (dests.get(i).lat < minlat)
				minlat = dests.get(i).lat;
			if (dests.get(i).lon > maxlon)
				maxlon = dests.get(i).lon;
			if (dests.get(i).lat > maxlat)
				maxlat = dests.get(i).lat;
		}

		LonLat center = new LonLat();
		center.SetLonLat((minlon + maxlon) / 2, (minlat + maxlat) / 2);
		Start.getInstance().MapKit().setMapCenter(center);
		double MAPSCALE[] = { 10.0, 50.0, 125.0, 250.0, 500.0, 1000.0, 2500.0,
				5000.0, 10000.0, 25000.0, 50000.0, 100000.0, 150000.0 /*
																	 * ,
																	 * 200000.0,
																	 * 400000.0
																	 */};

		int i = 0;
		for (i = 0; i < MAPSCALE.length; i++) {
			Start.getInstance().MapKit().setScale(MAPSCALE[12 - i]);
			LonLat ld = new LonLat();
			LonLat ru = new LonLat();
			Start.getInstance().MapKit().getMapViewExtent(ld, ru);
			if (ld.GetLon() <= minlon && ld.GetLat() <= minlat
					&& ru.GetLon() >= maxlon && ru.GetLat() >= maxlat)
				break;
		}

		mMapView.setShowRoutePlanDests(true);
	}

	@Override
	protected void onResume() {
		if (!mIsOnMap) {
			NavPosition matchCar = mCar.getCarNavPos();
			matchCar.pos.lon = mCarll.GetLon();
			matchCar.pos.lat = mCarll.GetLat();
			matchCar.signal = 100;
			mCar.setCarNavPos(matchCar);
			updateMapView();
		}

		if (!mIsOnMap
				&& mPosProvider.getProviderMode() != PositionProvider.PATHSIMU_PROVIDER
				&& mMapMode == MOVING_MODE) {
			double lon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
			double lat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
			mCar.setFreeMoving(true);
			mCarll.SetLonLat(lon, lat);
			NavPosition matchCar = mCar.getCarNavPos();
			matchCar.pos.lon = lon;
			matchCar.pos.lat = lat;
			mCar.setCarNavPos(matchCar);
			updateMapView();
		}

		// 接受SensorManager的一个列表(Listener)
		// 这里我们指定类型为TYPE_ORIENTATION(方向感应器)
		@SuppressWarnings("deprecation")
		List<Sensor> sensors = mSensorManager
				.getSensorList(Sensor.TYPE_ORIENTATION);

		if (sensors.size() > 0) {
			Sensor sensor = sensors.get(0);
			// 注册SensorManager
			// this->接收sensor的实例
			// 接收传感器类型的列表
			// 接受的频率
			mRegisteredSensor = mSensorManager.registerListener(this, sensor,
					SensorManager.SENSOR_DELAY_FASTEST);
		}

		_isActive = true;
		super.onResume();
	}

	boolean _isActive = false;

	@Override
	protected void onPause() {
		_isActive = false;
		if (mRegisteredSensor) {
			// 如果调用了registerListener
			// 这里我们需要unregisterListener来卸载/取消注册
			mSensorManager.unregisterListener(this);
			mRegisteredSensor = false;
		}
		super.onPause();
	}

	private void initUI() {
		setContentView(R.layout.activity_map);

		mMapView = (MapView) this.findViewById(R.id.id_mapview);
		mNaviInfoView = (NaviInfoView) findViewById(R.id.id_naviinfo);
		mLocal = (ImageButton) findViewById(R.id.btnlocal);
		mNaviinfo = (ImageButton) findViewById(R.id.btnNaviinfo);
		mNaviinfo.setVisibility(View.GONE);
		mZoom = (ZoomView) findViewById(R.id.id_zoomview);
		mNavimodectrlView = (NaviModeCtrlView) findViewById(R.id.id_navimodectrlview);

		mScale = (TextView) findViewById(R.id.id_map_scalebar);
		mScale.setText(Start.getInstance().MapKit().getScaleString());

		mSearch = (FrameLayout) findViewById(R.id.search_ctrl);

		mSimuCtrl = (FrameLayout) findViewById(R.id.navi_simuctrl);
		mSimuCtrl.setVisibility(View.GONE);

		mMapView.setCar(mCar);
		mNavimodectrlView.setCar(mCar);

		// tipinfo
		mTipInfo = (TipInfoView) findViewById(R.id.id_tipinfoview);
		mTipInfo.setVisibility(View.GONE);
		mTipInfo.setOnClickListener(this);

		mNaviInfoView.mTurn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				onRouteInfo();
			}
		});

		TextView textview = (TextView)findViewById(R.id.id_fonticon);
		textview.setTypeface(AppContext.getInstances().getIconfont());
	}

	@SuppressLint("HandlerLeak")
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case Msg.UPDATEPOS:
				updateNaviMap(mPosProvider.mNavpos);
				break;
			case Msg.SHOWTIP:
				onShowTip();
				break;
			case Msg.UPDATEMAP:
				updateMapView();
				break;
			case Msg.FINISHUPDATEMAP:
				finishUpdatedMapView();
				break;
			case Msg.BEGINROUTE:
				onRoute();
				break;
			case Msg.FINISHROUTE:
				onFinishRoute();
				break;
			case Msg.SEARCHFINISH:
				break;
			case Msg.UPDATETRACELOG:
				break;
			}
		}
	};

	LonLat mTipll = new LonLat();
	private int mTipIndex = 0;
	private String mTipname = "";

	private void onShowTip() {
		if (NAVI_MODE == mMapMode)
			return;

		if (Utils.isFastDoubleClick())
			return;

		try {
			mTipIndex = 0;
			mTipll = mMapView.getTipLL();
			if (mTipll.IsValid()) {
				if (showFav()) {
					return;
				}
				Start.getInstance().MapKit().mTipPoiList = Start.getInstance()
						.MapKit().getNearPoi(mTipll, true);
				if (Start.getInstance().MapKit().mTipPoiList.size() < 1) {
					Toast.makeText(this, "附近无道路请重新选择。", Toast.LENGTH_SHORT)
							.show();
					return;
				}

				showPosInfo(mTipIndex);
			}
		} catch (Exception e) {
		}
	}

	private boolean showFav() {
		if (mIsOnMap) {
			return false;
		}

		ArrayList<FavoriteData> listFavorite = mMapView.listDrawFavorite;
		
		Point tipPos = new Point();
		tipPos = Start.getInstance().MapKit().LL2XY(mTipll);
		int minX = tipPos.x - 50;
		int minY = tipPos.y - 50;
		int maxX = tipPos.x + 50;
		int maxY = tipPos.y + 50;

		int favcount = listFavorite.size();
		for (int i = 0; i < favcount; ++i) {
			FavoriteData data = listFavorite.get(i);
			if (data.countryID
					.compareToIgnoreCase("CN") != 0)
				continue;

			if (data.icon != 8)
				continue;

			LonLat ll = new LonLat(data.lon, data.lat);
			
			Point favPos = new Point();
			favPos = Start.getInstance().MapKit().LL2XY(ll);
			if (favPos.x < minX || favPos.y < minY || favPos.x > maxX
					|| favPos.y > maxY)
				continue;

			FavoriteFileHandle.getInstance().editFav = data;
			data.eid = -1;
//			Intent intent = new Intent(this, ShowFavPicActivity.class);
//			startActivityForResult(intent, 888888888);
			return true;
		}

		return false;
	}

	private void showPosInfo(int index) {
		if (index < 0 || index >= Start.getInstance().MapKit().mTipPoiList.size())
			return;

		POIDescription poiData = Start.getInstance().MapKit().mTipPoiList.get(index);
		mTipname = poiData.name;
		if (mTipname.length() > 1) {
			mTipname = mTipname.replace("*", "\n");
		}

		mTipname = mTipname.trim();
		mTipInfo.setText(mTipname);
	}

	private void showPOIInfo(int pos) {
		if (pos < 0 || pos >= Start.getInstance().MapKit().mPOIResult.size())
			return;

		POIDescription poiData = Start.getInstance().MapKit().mPOIResult.get(pos);
		mTipname = poiData.name;
		if (mTipname.length() > 1) {
			mTipname = mTipname.replace("*", " ");
		}
		mTipInfo.setText(mTipname);
	}

	// <---- button响应
	public static final int FORSEARCHPOI = 579;

	public void onSearch(View v) {
		if (mIsOnMap) {
			return;
		}

		if (Utils.isFastDoubleClick())
			return;

		toSearch("");
	}

	public void toSearch(String strKey) {
		setActive(false);
		mCenterll = Start.getInstance().MapKit().getMapCenter();
		Intent intent = new Intent(this, SearchActivity.class);
		startActivityForResult(intent, FORSEARCHPOI);
	}

	private void firstSendPos() {
		NavPosition navpos = NavFrameSDK.getInstance().new NavPosition();
		navpos.pos.lon = Start.getInstance().MapKit().mNavStart.pos.lon;
		navpos.pos.lat = Start.getInstance().MapKit().mNavStart.pos.lat;
		LonLat pos = new LonLat(navpos.pos.lon, navpos.pos.lat);
		navpos.signal = 6;
		navpos.vel = 2000;
		navpos.dir = mSensorDegree;

		if (pos.IsInvalid()
				|| PositionProvider.getInstance().getProviderMode() != PositionProvider.PATHSIMU_PROVIDER) {
//			navpos.pos.lon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
//			navpos.pos.lat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
			navpos.pos.lon = SysUtils.getInstance().getLL().GetLon();
			navpos.pos.lat = SysUtils.getInstance().getLL().GetLat();
		}
		updateNaviMap(navpos);
	}

	// 回现地
	public void onLocal(View v) {
		if (Utils.isFastDoubleClick())
			return;

		mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
		mPosProvider.begin();
		backToNavi();
	}

	void backToNavi() {
		initWnd(NAVI_MODE);
		firstSendPos();
	}

	public void onOverNavi(View v) {
		new AlertDialog.Builder(this).setTitle(getString(R.string.dlg_title))
				.setMessage("是否结束本次导航？")
				.setPositiveButton("确定", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						mSimuCtrl.setVisibility(View.GONE);
						mPosProvider
								.setProviderMode(PositionProvider.GPS_PROVIDER);
						mPosProvider.begin();
						Start.getInstance().MapKit().clearRoute();
						Start.getInstance().MapKit().clearNavStart();
						Start.getInstance().MapKit().mNavDest = null;
						initWnd(MOVING_MODE);
					}
				}).setNegativeButton("取消", null).show();
	}

	public void onStopSimu(View v) {
		overSimu();
	}

	@SuppressWarnings("deprecation")
	public void onSimuAdd(View v) {
		ImageButton btnSimuadd = (ImageButton) findViewById(R.id.btnSimuAdd);
		int index = mPosProvider.setSimuStep(true);
		switch (index) {
		default:
		case 1:
			btnSimuadd.setBackgroundDrawable(getResources().getDrawable(
					R.drawable.selector_btn_add1));
			break;
		case 2:
			btnSimuadd.setBackgroundDrawable(getResources().getDrawable(
					R.drawable.selector_btn_add2));
			break;
		case 4:
			btnSimuadd.setBackgroundDrawable(getResources().getDrawable(
					R.drawable.selector_btn_add3));
			break;
		case 8:
			btnSimuadd.setBackgroundDrawable(getResources().getDrawable(
					R.drawable.selector_btn_add4));
			break;
		}
	}

	// 模拟
	@SuppressWarnings("deprecation")
	void beginSimu() {
		mPosProvider.setProviderMode(PositionProvider.PATHSIMU_PROVIDER);
		mPosProvider.begin();

		findViewById(R.id.btnSimuAdd).setBackgroundDrawable(
				getResources().getDrawable(R.drawable.selector_btn_add1));
		mSimuCtrl.setVisibility(View.VISIBLE);
	}

	void overSimu() {
		initWnd(MOVING_MODE);
		onRouteInfo();
	}

	public void onZoomIn(View v) {
		autoBackNavi = 0;
		Start.getInstance().MapKit().onZoomIn();
		if (mMapMode == NAVI_MODE) {
			Start.getInstance().MapKit().setPosition(mCar.getCarPos(), mCarll);
		}
		updateMapView();
	}

	public void onZoomOut(View v) {
		autoBackNavi = 0;
		Start.getInstance().MapKit().onZoomOut();
		if (mMapMode == NAVI_MODE) {
			Start.getInstance().MapKit().setPosition(mCar.getCarPos(), mCarll);
		}
		updateMapView();
	}

	public void onRouteplan(View v) {
		if (Utils.isFastDoubleClick())
			return;
		setActive(false);
		mCenterll = Start.getInstance().MapKit().getMapCenter();
		RoutePlanActivity.launch(this, 1);
	}

	public void onRouteInfo() {
		mSimuCtrl.setVisibility(View.GONE);
		mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
		mPosProvider.begin();
		setActive(false);
		Intent intent = new Intent(this, NewRouteInfoActivity.class);
		intent.putExtra("noTurnLimit", noTurnLimitMode);
		startActivityForResult(intent, Msg.TO_NAVIINFO);
	}

	public void onSearcharound(View v) {
		if (Utils.isFastDoubleClick())
			return;

		if (mIsOnMap && !fromfav_) {
			setResult(Msg.MAP_SEARCHARROUNT);
			finish();
		} else {
			searchArround();
		}
	}

	public void searchArround() {
		setActive(false);
		mCenterll = Start.getInstance().MapKit().getMapCenter();
		Intent intent = new Intent(this, SearchAroundActivity.class);
		startActivityForResult(intent, FORSEARCHPOI);
	}

	public void onBack(View v) {
		if (Utils.isFastDoubleClick())
			return;

		finish();
	}

	public void onDaynight(View v) {
		if (Utils.isFastDoubleClick())
			return;
		if (Start.getInstance().MapKit().mMapDNState == 1) {
			Start.getInstance().MapKit().setDNMode(0);
		} else {
			Start.getInstance().MapKit().setDNMode(1);
		}

		updateMapView();
	}

	public void onPopMaptools(View v) {
		if (Utils.isFastDoubleClick())
			return;
		mTipInfo.setVisibility(View.GONE);
	}

	public void onCloseMaptools(View v) {
		if (Utils.isFastDoubleClick())
			return;
	}

	public void onCompass(View v) {
		if (Utils.isFastDoubleClick())
			return;

		mNavimodectrlView.change();
		Start.getInstance().MapKit().setPosition(mCar.getCarPos(), mCar.getCarLL());
		updateMapView();
	}

	public void on2D(View v) {
		if (Utils.isFastDoubleClick())
			return;

		mNavimodectrlView.changeNavimode(2);
		Start.getInstance().MapKit().setPosition(mCar.getCarPos(), mCar.getCarLL());
		updateMapView();
	}

	public void on3D(View v) {
		if (Utils.isFastDoubleClick())
			return;

		// ->North
		mNavimodectrlView.changeNavimode(2);
		Start.getInstance().MapKit().setPosition(mCar.getCarPos(), mCar.getCarLL());
		updateMapView();
	}

	public void onNorth(View v) {
		if (Utils.isFastDoubleClick())
			return;
		// ->2D
		mNavimodectrlView.changeNavimode(0);
		Start.getInstance().MapKit().setPosition(mCar.getCarPos(), mCar.getCarLL());
		updateMapView();
	}

	public void onNaviinfo(View v) {
		if (Utils.isFastDoubleClick())
			return;

		onRouteInfo();
	}

	public void onTipcar(View v) {
		if (Utils.isFastDoubleClick())
			return;

		if (mTipll == null)
			return;
		if (!mTipll.IsValid())
			return;

		Start.getInstance().MapKit().setCarRouteOption();

		Start.getInstance().MapKit().mNavDest = new NavDest[1];
		Start.getInstance().MapKit().mNavDest[0] = NavFrameSDK.getInstance().new NavDest();
		Start.getInstance().MapKit().mNavDest[0].pos.lon = mTipll.GetLon();
		Start.getInstance().MapKit().mNavDest[0].pos.lat = mTipll.GetLat();
		Start.getInstance().MapKit().mNavDest[0].name = mTipname;
		Start.getInstance().MapKit().mNavDest[0].eid = 0;

		Start.getInstance().MapKit().clearNavStart();

		if (mIsOnMap) {
			setResult(Msg.NAVI_TO_DEST);
			finish();
		} else {
			mHandler.sendEmptyMessage(Msg.BEGINROUTE);
		}
	}

	private void ChangeRouteMgrData() {
		HistoryData newdata = new HistoryData();
		newdata.lon = mTipll.GetLon();
		newdata.lat = mTipll.GetLat();
		newdata.name = mTipname;

		if (1 == mFromRouteMgrType) {
			RoutePlanDataHandle.getInstance().setStart(newdata);
		} else if (2 == mFromRouteMgrType && mFromRouteMgrDestIndex >= 0) {
			RoutePlanDataHandle.getInstance().changeDest(newdata,
					mFromRouteMgrDestIndex);
		} else if (3 == mFromRouteMgrType) {
			RoutePlanDataHandle.getInstance().addDest(newdata);
		}

		setResult(Msg.CHANGE_ROUTEMGR);
		finish();
	}

	public void onTipname(View v) {
		if (Utils.isFastDoubleClick())
			return;

		if (mFromRouteMgrType != -1) {
			ChangeRouteMgrData();
			return;
		}

		mCenterll = Start.getInstance().MapKit().getMapCenter();

		setActive(false);
		autoBackNavi = 0;

		Start.getInstance().MapKit().mTipPoiList = Start.getInstance().MapKit().getNearPoi(
				mTipll, false);
	}

	public void onTipman(View v) {
		if (Utils.isFastDoubleClick())
			return;

		if (mTipll == null)
			return;
		if (!mTipll.IsValid())
			return;

		Start.getInstance().MapKit().mNavDest = new NavDest[1];
		Start.getInstance().MapKit().mNavDest[0] = NavFrameSDK.getInstance().new NavDest();
		Start.getInstance().MapKit().mNavDest[0].pos.lon = mTipll.GetLon();
		Start.getInstance().MapKit().mNavDest[0].pos.lat = mTipll.GetLat();
		Start.getInstance().MapKit().mNavDest[0].name = mTipname;
		Start.getInstance().MapKit().mNavDest[0].eid = 0;

		Start.getInstance().MapKit().clearNavStart();

		if (mIsOnMap) {
			setResult(Msg.NAVI_TO_DEST);
			finish();
		} else {
			mHandler.sendEmptyMessage(Msg.BEGINROUTE);
		}
	}

	// button响应--->
	private void updateMapView() {
		mMapView.invalidate();
		finishUpdatedMapView();
		mZoom.updateState();
	}

	private void finishUpdatedMapView() {
		mScale.setText(Start.getInstance().MapKit().getScaleString());
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		autoBackNavi = 0;
		if (mIsRouting)
			return true;
		mTipInfo.setVisibility(View.GONE);

		if (PositionProvider.PATHSIMU_PROVIDER == mPosProvider
				.getProviderMode()) {
			mMapView.onMouseEvent(event);
			if (event.getAction() == MotionEvent.ACTION_UP) {
				if (mMapView.needTip) {
					autoBackNavi = 0;
					mCar.setFreeMoving(true);
					Start.getInstance().MapKit().setRotation(0);
				}
				updateMapView();
			} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
				mCar.setFreeMoving(true);
				Start.getInstance().MapKit().setRotation(0);
				autoBackNavi = 0;
				updateMapView();
			}
			return super.onTouchEvent(event);
		}

		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			initWnd(MOVING_MODE);
		}

		mMapView.onMouseEvent(event);

		if (event.getAction() == MotionEvent.ACTION_UP) {
			if (mMapView.needTip) {
				mHandler.sendEmptyMessage(Msg.SHOWTIP);
			}

			updateMapView();
		} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
			updateMapView();
		}

		return super.onTouchEvent(event);
	}

	// MapMode -- 移图模式/导航模式
	public final int MOVING_MODE = 0;
	public final int NAVI_MODE = 1;
	private int mMapMode = -1;

	private void initWnd(int mapMode) {
		mMapMode = mapMode;

		if (MOVING_MODE == mapMode) {
			mSimuCtrl.setVisibility(View.GONE);
			if (mPosProvider.getProviderMode() == PositionProvider.PATHSIMU_PROVIDER
					&& !mIsOnMap) {
				double lon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
				double lat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
				mCarll.SetLonLat(lon, lat);
				NavPosition matchCar = mCar.getCarNavPos();
				matchCar.pos.lon = lon;
				matchCar.pos.lat = lat;
				matchCar.signal = 100;
				mCar.setCarNavPos(matchCar);
				mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
				mPosProvider.begin();
			}

			mNaviInfoView.setVisibility(View.GONE);
			mLocal.setVisibility(View.VISIBLE);
			mSearch.setVisibility(View.VISIBLE);
			Start.getInstance().MapKit().setRotation(0);
			Start.getInstance().MapKit().setMapViewMode(0);
			mCar.setFreeMoving(true);
			FrameLayout backctrl = (FrameLayout) findViewById(R.id.onmap_back_ctrl);
			backctrl.setVisibility(View.GONE);
			if (mIsOnMap) {
				mLocal.setVisibility(View.GONE);
				mSearch.setVisibility(View.GONE);
				mNaviinfo.setVisibility(View.GONE);
				backctrl.setVisibility(View.VISIBLE);
			}
			mNavimodectrlView.setPadding(0, 0, 0, 0);

		} else if (NAVI_MODE == mapMode) {
			mCar.setFreeMoving(false);
			mNaviInfoView.setVisibility(View.VISIBLE);
			mLocal.setVisibility(View.GONE);
			mTipInfo.setVisibility(View.GONE);
			Start.getInstance().MapKit().setScale(100000);
			mZoom.updateState(0);
			if (Start.getInstance().isHavePath()) {
				mNavimodectrlView.setPadding(0, 150, 0, 0);
				mSearch.setVisibility(View.GONE);
			}
			mNavimodectrlView.show();
		}

		updateMapView();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (!mIsOnMap) {
			setActive(true);
		}

		if (resultCode == Msg.TOMAPMANAGER) {
			setResult(Msg.TOMAPMANAGER);
			finish();
			return;
		}

		if (resultCode == Msg.MAP_SEARCHARROUNT) {
			if (mIsOnMap && !fromfav_) {
				setResult(resultCode);
				finish();
			} else {
				searchArround();
				return;
			}
		}

		if (requestCode == 888888888) {
			super.onActivityResult(requestCode, resultCode, data);
			return;
		}

		if (resultCode != Msg.NAVI_SIMU) {
			Start.getInstance().MapKit().setMapCenter(mCenterll);
			Start.getInstance().MapKit().setScale(100000);
			updateMapView();
		}

		if (resultCode == Msg.BACK_MAP_ID) {
			if (requestCode == Msg.TO_NAVIINFO)
				return;

			if (requestCode != Msg.TO_TIPDETAIL) {
				mTipInfo.setVisibility(View.GONE);
				initWnd(MOVING_MODE);
			}
			return;
		}

		if (resultCode == Msg.OVER_NAVI) {
			if (mIsOnMap) {
				setResult(resultCode);
				finish();
				return;
			} else {
				mSimuCtrl.setVisibility(View.GONE);
				mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
				mPosProvider.begin();
				Start.getInstance().MapKit().clearRoute();
				Start.getInstance().MapKit().clearNavStart();
				Start.getInstance().MapKit().mNavDest = null;
				Start.getInstance().setHavePath(false);
				initWnd(MOVING_MODE);
				return;
			}
		}

		if (resultCode == Msg.NAVI_TO_DEST) {
			if (mIsOnMap) {
				setResult(resultCode);
				finish();
			} else {
				DoNaviToDest();
			}
			return;
		}

		if (resultCode == Msg.NAVI_SIMU) {
			if (mIsOnMap) {
				setResult(resultCode);
				finish();
				return;
			} else {
				beginSimu();
				backToNavi();
				return;
			}
		}

		if (resultCode == Msg.NAVI_TONAVI) {
			if (mIsOnMap) {
				setResult(resultCode);
				finish();
				return;
			} else {
				if (Start.getInstance().MapKit().mNavStart.pos.lon != 0) {
					double lon = SystemSetFileHandle.getInstance()
							.getSystemSet().previewLon;
					double lat = SystemSetFileHandle.getInstance()
							.getSystemSet().previewLat;
					mCarll.SetLonLat(lon, lat);
					if (Start.getInstance().MapKit().mNavDest != null
							&& Start.getInstance().MapKit().mNavDest.length > 0) {
						int index = Start.getInstance().MapKit().mNavDest.length - 1;
						double lon1 = Start.getInstance().MapKit().mNavDest[index].pos.lon;
						double lat1 = Start.getInstance().MapKit().mNavDest[index].pos.lat;
						if (mCarll.IsSame(lon1, lat1)) {
							Toast.makeText(this, "已到达目的地结束导航。",
									Toast.LENGTH_SHORT).show();
							Start.getInstance().MapKit().clearRoute();
							Start.getInstance().MapKit().clearNavStart();
							Start.getInstance().MapKit().mNavDest = null;
							Start.getInstance().setHavePath(false);
						}
					}
				}
				Start.getInstance().MapKit().clearNavStart();
				mSimuCtrl.setVisibility(View.GONE);
				backToNavi();
				mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
				mPosProvider.begin();
				return;
			}
		}

		if (requestCode == FORSEARCHPOI) {
			if (mIsOnMap) {
				setResult(resultCode);
				finish();
			} else {
				showPOIInfo(resultCode);
				updateMapView();
			}
			return;
		}

		if (!mIsOnMap) {
			backToNavi();
		}

		super.onActivityResult(requestCode, resultCode, data);
	}

	private void DoNaviToDest() {
		setActive(false);
		mHandler.sendEmptyMessage(Msg.BEGINROUTE);
	}

	private void setActive(boolean isActive) {
		if (!isActive) {
			autoBackNavi = 0;
		}
		_isActive = isActive;
	}

	private int mRouteEcode = -1;
	private boolean mIsRouting = false;

	private void onRoute() {
		mTipInfo.setVisibility(View.GONE);

		mPB = new ProgressDialog(this);
		mPB.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		mPB.setMessage(getString(R.string.navi_routing_progress));
		mPB.setCancelable(false);
		mPB.setOnCancelListener(new OnCancelListener() {
			@Override
			public void onCancel(DialogInterface arg0) {
			}
		});
		setActive(false);

		mPB.setMax(100);
		mPB.setProgress(0);
		mPB.show();

		mIsRouting = true;
		new Thread() {
			@Override
			public void run() {
				beginRoute();
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				mHandler.sendEmptyMessage(Msg.FINISHROUTE);
			}
		}.start();

		Timer processTimer = new Timer();
		processTimer.schedule(new TimerTask() {
			@Override
			public void run() {
				int process = Start.getInstance().MapKit().getRoutingProcess();
				if (mPB != null) {
					mPB.setProgress(process);
				} else {
					cancel();
				}
			}
		}, 500, 500);
	}

	private void beginRoute() {
		mRouteEcode = -1;
		Start.getInstance().MapKit().clearRoute();
		if (Start.getInstance().MapKit().mNavDest == null
				|| Start.getInstance().MapKit().mNavDest.length < 1) {
			return;
		}

		mIsRouting = true;
		Start.getInstance().setHavePath(false);

		if (Start.getInstance().MapKit().mNavStart.pos.lon == 0) {
			NavPosition navpos = NavFrameSDK.getInstance().new NavPosition();
			if (mPosProvider.getGPSNumBmpPath() == 0
					|| !mPosProvider.getGPSData()) {
				navpos = mPosProvider.mNavpos;
				navpos.pos.lon = SystemSetFileHandle.getInstance()
						.getSystemSet().previewLon;
				navpos.pos.lat = SystemSetFileHandle.getInstance()
						.getSystemSet().previewLat;
				navpos.dir = -1;
			}
			Start.getInstance().MapKit().mNavStart.pos = navpos.pos;
			Start.getInstance().MapKit().mNavStart.pname = 0;
			Start.getInstance().MapKit().mNavStart.name = "";
			Start.getInstance().MapKit().mNavStart.dir = navpos.dir;
		}

		for (int i = 0; i < Start.getInstance().MapKit().mNavDest.length; i++) {
			HistoryData his = new HistoryData();
			his.lon = Start.getInstance().MapKit().mNavDest[i].pos.lon;
			his.lat = Start.getInstance().MapKit().mNavDest[i].pos.lat;
			his.name = Start.getInstance().MapKit().mNavDest[i].name;
			HistoryFileHandle.getInstance().add(his);
		}
		
		mRouteEcode = Start.getInstance().MapKit().route(Start.getInstance().MapKit().mNavStart,
				Start.getInstance().MapKit().mNavDest, null);
		noTurnLimitMode = false;
		if(mRouteEcode == 113) {
			if(Start.getInstance().MapKit().isCarRouteOption()){
				noTurnLimitMode = true;
				Start.getInstance().MapKit().setCarRouteOptionNoLimit();
				mRouteEcode = Start.getInstance().MapKit().route(Start.getInstance().MapKit().mNavStart,
						Start.getInstance().MapKit().mNavDest, null);
			}
			
		}
	}
	private boolean noTurnLimitMode = false;
	private ProgressDialog mPB = null;

	private void onFinishRoute() {
		mIsRouting = false;
		if (mPB != null) {
			mPB.dismiss();
			mPB = null;
		}

		mIsRouting = false;

		if (mRouteEcode == 0) {
			Start.getInstance().setHavePath(true);
			String strRemainDistance = "";
			try {
				if (Start.getInstance().MapKit().prepareTurnAndGuid()) {
					TurnInfo turnInfo = NavFrameSDK.getInstance().new TurnInfo();
					GuideInfo guidInfo = NavFrameSDK.getInstance().new GuideInfo();
					CLonLat pPos = NavFrameSDK.getInstance().new CLonLat();
					if (Start.getInstance().MapKit().nextTurnAndGuid(turnInfo, guidInfo,
							pPos)) {
						strRemainDistance = Start.getInstance()
								.MapKit().getDistanceString(
										(int) guidInfo.remainDistance);
						strRemainDistance = strRemainDistance.replace("km",
								getString(R.string.lenth_km));
						strRemainDistance = strRemainDistance.replace("m",
								getString(R.string.lenth_m));
					}
					Start.getInstance().MapKit().finishTurnAndGuid();
				}
			} catch (Exception e) {
			}

			onRouteInfo();
			return;
		} else {
			Start.getInstance().MapKit().clearRoute();
			Start.getInstance().MapKit().mNavDest = null;
			String strErr = getString(R.string.path_calculation_fails);
			switch (mRouteEcode) {
			case 110: // ERR_ROUTE_ORIGIN_INVALID
				strErr += getString(R.string.route_errcode_1);
				break;
			case 111: // ERR_ROUTE_DEST_INVALID
				strErr += getString(R.string.route_errcode_2);
				break;
			case 112: // ERR_ROUTE_DEST_ORIGIN_CLOSE
				strErr += getString(R.string.route_errcode_3);
				break;
			}

			Start.getInstance().setHavePath(false);
			mNaviInfoView.setHavepath(false);
			mMapMode = -1;
			initWnd(NAVI_MODE);
			Toast.makeText(this, strErr, Toast.LENGTH_SHORT).show();
		}

		setActive(true);
		Start.getInstance().MapKit().showFullPath();
		mHandler.sendEmptyMessage(Msg.UPDATEMAP);
	}

	public void alert(String str) {
		Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	// 当传感器在被改变时触发
	@SuppressWarnings("deprecation")
	@Override
	public void onSensorChanged(SensorEvent event) {
		// 接受方向感应器的类型
		if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
			// 这里我们可以得到数据，然后根据需要来处理
			float degree = event.values[SensorManager.DATA_X];
			if (Math.abs(mSensorDegree - degree) > 10) {
				mSensorDegree = degree;

				// if (mMapMode == MOVING_MODE) {
				Point e = mCar.getCarPos();
				if (e.x > 0 && e.x < 400 && e.y > 0 && e.y < 800) {
					mCar.setCarHeading(mSensorDegree);
					mMapView.invalidate();
				}
				// }
			}
		}
	}

	int autoBackNavi = 0; // > 10 自动返回导航

	// 开始导航后 速度 > 30，确定为 行车模式，才粘贴道路. 10次
	int carmodeCount = 0;

	private void updateNaviMap(NavPosition navpos) {
		if (mIsOnMap) {
			return;
		}

		if (navpos.pos.lon == 0) {
			navpos.pos.lon = SysUtils.getInstance().getLL().GetLon();
			navpos.pos.lat = SysUtils.getInstance().getLL().GetLat();
		}

		if (PositionProvider.PATHSIMU_PROVIDER == mPosProvider
				.getProviderMode() && mCar.isFreeMoving()) {
			autoBackNavi++;
			if (autoBackNavi > 3) {
				mCar.setFreeMoving(false);
			}
			return;
		}

		if (mMapMode == MOVING_MODE && Start.getInstance().isHavePath()) {
			if (Start.getInstance().isHavePath() && !mIsRouting) {
				autoBackNavi++;
			} else {
				autoBackNavi = 0;
			}

			if (autoBackNavi > 3) {
				backToNavi();
				return;
			}
		}

		if (mIsRouting || mMapMode == MOVING_MODE) {
			if (mSensorDegree > 0
					&& PositionProvider.PATHSIMU_PROVIDER != mPosProvider
							.getProviderMode()) {
				mCar.setCarHeading(mSensorDegree);
			}
			return;
		}

		if (navpos.signal < 20 && navpos.vel > 30) {
			carmodeCount++;
		}

		boolean isSimu = false;
		if (PositionProvider.PATHSIMU_PROVIDER == mPosProvider
				.getProviderMode()) {
			isSimu = true;
		} else {
			autoBackNavi = 0;
		}
		mScale.setText(Start.getInstance().MapKit().getScaleString());
		mCarll.SetLonLat(navpos.pos.lon, navpos.pos.lat);

		NavPosition matchedPos = NavFrameSDK.getInstance().new NavPosition();
		NavInfo navInfo = NavFrameSDK.getInstance().new NavInfo();
		SDCurPosStates state = SDCurPosStates.SDCURPOSSTATE_NONE;

		if (!isSimu && mSensorDegree > 0 && navpos.vel < 20) {
			navpos.dir = mSensorDegree;
			// alert("mSensorDegree = " + mSensorDegree);
		}

		try {
			// matchedPos = navpos;
			state = Start.getInstance().MapKit().UpdatePosition(navpos, matchedPos,
					navInfo);

			if (navInfo.guidInfo.distanceToTurn > 5000000) {
				return;
			}

			if (carmodeCount < 10) {
				matchedPos = navpos;
			}

			String sentence = navInfo.sentence;
			if (sentence.length() > 3) {
				TtsSpeaker.getInstance().talk(sentence);
			}
		} catch (Exception e) {
			return;
		}

		if (Start.getInstance().isHavePath()) {
			if (isSimu) {
				// 接近中途点时放慢模拟速度
				if (navInfo.guidInfo.remainDistance < 200
						&& navInfo.guidInfo.remainDistance > 0) {
					mPosProvider.setSimuCloseDest(true);
				} else {
					mPosProvider.setSimuCloseDest(false);
				}
			}

			if (state == SDCurPosStates.SDCURPOSSTATE_DEVIATE) {
				// reRoute();
				if (!isSimu) {
					Start.getInstance().MapKit().reroute(false);
					return;
				}
				state = SDCurPosStates.SDCURPOSSTATE_NONE;
			} else if (state == SDCurPosStates.SDCURPOSSTATE_ARRIVED_DEST) {
				if (isSimu) {
					overSimu();
					return;
				} else {
					Start.getInstance().MapKit().clearRoute();
					Start.getInstance().MapKit().clearNavStart();
					Start.getInstance().MapKit().mNavDest = null;
					Start.getInstance().setHavePath(false);
				}
			} else if (state == SDCurPosStates.SDCURPOSSTATE_ARRIVED_MIDDLE_DEST) {

			}
		}

		if (state == SDCurPosStates.SDCURPOSSTATE_NONE) {
			mCarll.SetLonLat(matchedPos.pos.lon, matchedPos.pos.lat);
			navpos.dir = matchedPos.dir;
		}

		if (mMapMode == NAVI_MODE) {
			mNaviInfoView.setHavepath(Start.getInstance().isHavePath());
			mNaviInfoView.setNavInfo(navInfo, matchedPos);
		}

		if (!isSimu && navpos.vel < 15 && mSensorDegree > 0) {
			matchedPos.dir = mSensorDegree;
			// alert("mSensorDegree = " + mSensorDegree);
		}
		mCar.setCarNavPos(matchedPos);

		double heading = 0.0;
		if (mCar.getCarposMode() == Car.BOTTOMCENTER) {
			heading = matchedPos.dir;
		}

		Start.getInstance().MapKit().setRotation(heading);
		Point carPos = mCar.getCarPos();
		Start.getInstance().MapKit().setPosition(carPos, mCarll);

		updateMapView();
		mNavimodectrlView.setCompass();
	}

	@Override
	public void finish() {
		if (!mIsOnMap) {
			mSimuCtrl.setVisibility(View.GONE);
			mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
		}

		mMapMode = MOVING_MODE;
		TtsSpeaker.getInstance().stopCurrentVoice();
		super.finish();
	}

	@Override
	public void updatePos(NavPosition navpos, boolean isNetPos) {
		//callback是在timer里的不能直接调用updateNaviMap，因为updateNaviMap里有刷UI
		if (_isActive) {
			mHandler.sendEmptyMessage(Msg.UPDATEPOS);
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
			if (mMapMode == NAVI_MODE) {
				if (mPosProvider.getProviderMode() == PositionProvider.PATHSIMU_PROVIDER) {
					onRouteInfo();
					return true;
				}

				if (Start.getInstance().isHavePath()) {
					onOverNavi(null);
				} else {
					mSimuCtrl.setVisibility(View.GONE);
					mPosProvider.setProviderMode(PositionProvider.GPS_PROVIDER);
					mPosProvider.begin();
					initWnd(MOVING_MODE);
				}

				return true;
			}
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
			case R.id.btnTipcar:
				onTipcar(null);
				break;
			case R.id.btnTipname:
				onTipname(null);
				break;
			case R.id.btnTipman:
				onTipman(null);
				break;
			default:
				break;
		}
	}

}
